home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OCFINC.PAK / AUTODEFS.H < prev    next >
C/C++ Source or Header  |  1997-05-06  |  70KB  |  1,903 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.31  $
  6. //
  7. // OLE Automation Class Definitions
  8. //----------------------------------------------------------------------------
  9. #if !defined(OCF_AUTODEFS_H)
  10. #define OCF_AUTODEFS_H
  11.  
  12. #if !defined(OCF_DEFS_H)
  13. # include <ocf/defs.h>
  14. #endif
  15. #if !defined(OCF_OLEUTIL_H)
  16. # include <ocf/oleutil.h>
  17. #endif
  18. #if !defined(WINSYS_LCLSTRNG_H)
  19. # include <winsys/lclstrng.h>   // TLocaleString and TRegItem/TRegList
  20. #endif
  21. #if !defined(WINSYS_USTRING_H)
  22. # include <winsys/string.h>     // TString and TUString
  23. #endif
  24. #if !defined(__TYPEINFO_H)
  25. # include <typeinfo.h>          // C++ type info
  26. #endif
  27. #if !defined(_OLECTL_H_) && defined(BI_PLAT_WIN32)
  28. # if defined(__BIVBX_H) && !defined(NO_VBX_PICTURES)
  29. #   error BIVBX.H's LPPICTURE is incompatible with OLECTL.H - define NO_VBX_PICTURES
  30. # else
  31. #   define  NO_VBX_PICTURES     // Make sure we're BIVBX's compatible
  32. #   include <olectl.h>          // Ole Controls definitions
  33. # endif
  34. #endif
  35.  
  36. #if defined(BI_NAMESPACE)
  37. namespace OCF {
  38. #endif
  39.  
  40. //
  41. // Class modifier for inherited classes or members within user C++ classes
  42. // if ambient class model is not used, this macro must be defined to match
  43. //
  44. #if !defined(_AUTOCLASS)
  45. # define  _AUTOCLASS
  46. #endif
  47.  
  48. //
  49. // Forward class references
  50. //
  51. class _AUTOCLASS TAutoDetach;
  52. class _AUTOCLASS TAutoBase;
  53. class _ICLASS TAppDescriptor;  // defined in appdesc.h
  54. class _ICLASS TServedObject;
  55. class _ICLASS TAutoIterator;
  56. class TAutoCreator;
  57. class TAutoCommand;
  58. class TAutoSymbol;
  59. class TAutoString;
  60. class TAutoStack;
  61. class far TAutoVal;
  62. class TXAuto;
  63. class TAutoEnum;
  64.  
  65. const void far* DynamicCast(const void far* obj, const typeinfo& src,
  66.                                                  const typeinfo& dst);
  67. const void far* MostDerived(const void far* obj, const typeinfo& src);
  68.  
  69. //
  70. // Global function to invalidate external references, class model-independent
  71. //
  72. void SendObituary(const void far* obj, const typeinfo& typeInfo);
  73.  
  74. //----------------------------------------------------------------------------
  75. // Automation typedefs
  76. //
  77.  
  78. typedef unsigned long TLocaleId;   // locale ID - same as NT LCID
  79.  
  80. class _AUTOCLASS TAutoBase {   // default base for automatable objects
  81.   public:
  82.     virtual ~TAutoBase();// only member is virtual destructor for unregistration
  83. };
  84.  
  85. class _AUTOCLASS TAutoDetach { // default base for detach notification objects
  86.   protected:
  87.     void Notify(int offset, const typeinfo& typeInfo);  // sends obituary
  88. };          // the size of this object must be 0 to not affect enclosing class
  89.  
  90. typedef void* ObjectPtr;  // generic opaque object pointer
  91.  
  92. //
  93. // Generic conversion function for changing between inherited classes
  94.  
  95. //
  96. template <class T, class B> struct TTypeConvert {
  97.   static ObjectPtr Cast(ObjectPtr from) { return
  98.    reinterpret_cast<ObjectPtr>( dynamic_cast<T*>(reinterpret_cast<B*>(from)));
  99.   }
  100. };
  101.  
  102. typedef ObjectPtr      (*TAutoSymTypeConvert) (ObjectPtr obj);
  103. typedef TAutoCommand*  (*TAutoCommandBuild)(ObjectPtr obj,int attr,TAutoStack&);
  104. typedef TAutoCommand*  (*TAutoCommandBuildDtr)(ObjectPtr obj, int attr);
  105. typedef TAutoIterator* (*TAutoIteratorBuild)(ObjectPtr obj,
  106.                                              TAutoCreator& creator,
  107.                                              IUnknown* owner, TLangId lang);
  108. typedef IUnknown&      (*TAggregator)(ObjectPtr obj, TUnknown& inner);
  109.  
  110. extern "C" const GUID __cdecl IID_TServedObject;
  111.  
  112. //
  113. // class TXAuto
  114. // ~~~~~ ~~~~~~
  115. // Automation exception object
  116. //
  117. class TXAuto : public TXBase {
  118.   public:
  119.     enum TError {
  120.       xNoError,                 //  0
  121.       xConversionFailure,       //  1
  122.       xNotIDispatch,            //  2
  123.       xForeignIDispatch,        //  3
  124.       xTypeMismatch,            //  4
  125.       xNoArgSymbol,             //  5
  126.       xParameterMissing,        //  6
  127.       xNoDefaultValue,          //  7
  128.       xValidateFailure,         //  8
  129.       xExecutionFailure,        //  9
  130.       xErrorStatus,             // 10
  131.     };
  132.     TXAuto(TXAuto::TError err);
  133.     void          Throw();
  134.     static void   Raise(TXAuto::TError err);
  135.  
  136.   public:
  137.     TError ErrorCode;
  138. };
  139.  
  140. //----------------------------------------------------------------------------
  141. // TAutoType, TAutoClass - automation type/class descriptor
  142. //
  143.  
  144. struct TAutoType {
  145.     uint16 GetType() const {return Type;}
  146.     uint16 Type;
  147. };
  148.  
  149. class TAutoClass : public TAutoType {
  150.   public:
  151.     TAutoClass(TAutoSymbol* table, TAutoSymbol* classSymbol,
  152.                const typeinfo& typeInfo, TAggregator aggregator=0);
  153.    ~TAutoClass();
  154.  
  155.     short         CountCommands();    // forces counts to be set on first call
  156.     TAutoSymbol*  Lookup(char* name, TLangId lang, short symFlags, long far& id);
  157.     TAutoSymbol*  LookupArg(char* name, TLangId lang, TAutoSymbol* cmd,
  158.                             long far& retid);
  159.     TAutoSymbol*  FindId(long id, ObjectPtr& objptr);
  160.     TAutoSymbol*  FindFunction(unsigned index, MEMBERID& retId);
  161.     TAutoSymbol*  FindVariable(unsigned index, MEMBERID& retId);
  162.     TXAuto::TError Dispatch(ObjectPtr obj, TAutoCreator& creator,
  163.                             TUnknown& owner, int attr, TAutoStack& args,
  164.                             TAutoVal* retval);
  165.     TAutoSymbol*           GetTable() const;
  166.     TAutoSymbol*           GetClassSymbol() const;
  167.     short                  GetArgCount(TAutoSymbol& sym);
  168.     TAutoCommandBuildDtr   GetDestructor() const;
  169.     const typeinfo&        GetTypeInfo() const;
  170.     const char*            GetName(TLangId lang = TLocaleString::UserDefaultLangId) const;
  171.     const char*            GetDoc (TLangId lang = TLocaleString::UserDefaultLangId) const;
  172.     unsigned long          GetHelpId() const;
  173.     unsigned short         GetTypeFlags() const;
  174.     int                    GetImplTypeFlags() const;
  175.     unsigned short         GetCoClassFlags() const;
  176.     TAggregator            GetAggregator() const;
  177.     IUnknown&              Aggregate(ObjectPtr obj, TUnknown& inner);
  178.  
  179.   protected:
  180.     TAggregator Aggregator;  // aggregator function for C++ COM classes
  181.     short CommandCount;      // command count including bases, 0 if uncounted
  182.     short FunctionCount;     // number of symbols exposed as typelib functions
  183.     short VariableCount;     // number of symbols exposed as typelib variables
  184.     bool  AutoIds;           // generate ID's automatically if true (default)
  185.     TAutoSymbol* Table;      // pointer to array of symbol entries
  186.     TAutoSymbol* ClassSymbol;// pointer to class symbol (terminator)
  187.     const typeinfo& TypeInfo;// for validating type of data pointers
  188.     friend class TServedObject;
  189.  
  190.   private:
  191.     struct TAutoClassRef {   // element used for array of TAutoClass objects
  192.       TAutoClass* Class;
  193.       int         GuidOffset;
  194.     };
  195.     struct TExtLink;      // fwd declaration
  196.     static struct TClassList { // module-static TAutoClass data
  197.       int  CountAutoClasses();  // walks list in attatched DLLs
  198.       TAutoClassRef* MergeAutoClasses(TAutoClassRef* array);
  199.       TAutoClass* List;   // chain of autoclasses in THIS module
  200.       int         Count;  // count of classes in THIS module
  201.       TExtLink*   Link;   // chain of TAutoClass data for loaded DLLs
  202.     } ClassList;
  203.     struct TExtLink {      // doubly-linked list of external DLL data
  204.       TExtLink(TClassList* list, HINSTANCE module);
  205.      ~TExtLink();
  206.       TClassList* Classes;
  207.       HINSTANCE   Module; // module handle if dynmaically loaded, else 0
  208.       TExtLink*   Next;
  209.       TExtLink**  Prev;
  210.     };
  211.     TAutoClass*   NextClass;          // link to next class
  212.     friend class TExtLink;            // access to ClassList
  213.     friend class TClassList;          // access to TAutoClassRef
  214.     friend class TAppDescriptor;      // access to linkage information
  215.     friend class _ICLASS TTypeLibrary;// access to TAutoClassRef
  216.     friend class _ICLASS TCoClassInfo;// access to TAutoClassRef
  217.     friend class _ICLASS TOcControlEvent;     // access to AutoIds bool
  218. };
  219.  
  220. //----------------------------------------------------------------------------
  221. // TAuto(type) automation datatype encapsulations
  222. //
  223.  
  224. //
  225. // Class to implement assignent of void to TAutoVal
  226. //
  227. struct TAutoVoid {
  228.   static TAutoType ClassInfo;
  229. };
  230.  
  231. //
  232. // Class to implement assignment of VT_ERROR/DISP_E_PARAMNOTFOUND
  233. // (i.e. Optional arguments) to TAutoVal
  234. //
  235. struct TNoArg {
  236.    //
  237.    // Dummy structure
  238. };
  239.  
  240. //
  241. // Wrapper class to disambiguate automation date type from double
  242. //
  243. struct TAutoDate {
  244.   TAutoDate() : Date(0) {}
  245.   TAutoDate(double d) : Date(d) {}
  246.   operator double() { return Date; }
  247.   double Date;      // same as OLE DATE
  248.   static TAutoType ClassInfo;
  249. };
  250.  
  251. //struct TAutoCurrency : public CY {
  252. struct far TAutoCurrency {
  253.   uint32 Lo;
  254.   int32  Hi;
  255.  
  256.   operator CY& () {return *this;}
  257.  
  258.   static TAutoType ClassInfo;
  259. };
  260.  
  261. #if defined(BI_NO_BOOL)
  262.   // For suppressing compiler warnings when bool is not a type
  263.   //
  264.   struct TAutoBool {
  265.     TAutoBool() : B(0) {}
  266.     TAutoBool(bool b) : B(b) {}
  267.     TAutoBool(TBool b) : B(static_cast<bool>(b)) {}
  268.     operator bool() {return B;}
  269.     operator TBool() {return static_cast<TBool>(B);}
  270.     void operator =(bool b) {B = b;}
  271.     void operator =(TBool b) {B = static_cast<bool>(b);}
  272.     bool B;
  273.     static TAutoType ClassInfo;
  274.   };
  275.   // Needed for automating bool* when bool is not a type
  276.   //
  277.   struct TAutoBoolRef {  //
  278.     TAutoBoolRef() : P(0) {}
  279.     TAutoBoolRef(bool* p) : P(p) {}
  280.     TAutoBoolRef(TBool* p) : P((bool*)p) {}
  281.     operator bool*() {return P;}
  282.     void operator =(bool* p) {P = p;}
  283.     void operator =(TBool* p){P = (bool*)p;}
  284.     bool* P;
  285.     static TAutoType ClassInfo;
  286.   };
  287. #else
  288. struct TAutoBool      { static TAutoType ClassInfo; };
  289. struct TAutoBoolRef   { static TAutoType ClassInfo; };
  290. #endif
  291.  
  292. //
  293. // The following types do not hold data, but only provide static type codes
  294. //
  295. struct TAutoShort      { static TAutoType ClassInfo; };
  296. struct TAutoDouble     { static TAutoType ClassInfo; };
  297. struct TAutoFloat      { static TAutoType ClassInfo; };
  298. struct TAutoLong       { static TAutoType ClassInfo; };
  299. struct TAutoByte       { static TAutoType ClassInfo; };
  300. struct TAutoUnknown    { static TAutoType ClassInfo; };  // for raw IUnknown*
  301. struct TAutoDispatch   { static TAutoType ClassInfo; };  // for raw IDispatch*
  302. struct TAutoVariant    { static TAutoType ClassInfo; };
  303. struct TAutoShortRef   { static TAutoType ClassInfo; };
  304. struct TAutoLongRef    { static TAutoType ClassInfo; };
  305. struct TAutoFloatRef   { static TAutoType ClassInfo; };
  306. struct TAutoDoubleRef  { static TAutoType ClassInfo; };
  307. struct TAutoCurrencyRef{ static TAutoType ClassInfo; };
  308. struct TAutoDateRef    { static TAutoType ClassInfo; };
  309. struct TAutoStringRef  { static TAutoType ClassInfo; };
  310. struct TAutoVariantRef { static TAutoType ClassInfo; };
  311. struct TAutoSafeArray  { static TAutoType ClassInfo; };
  312. struct TAutoByteRef    { static TAutoType ClassInfo; };
  313. #if (MAXINT==MAXSHORT)
  314.   typedef TAutoShort    TAutoInt;
  315.   typedef TAutoShortRef TAutoIntRef;
  316. #else
  317.   typedef TAutoLong    TAutoInt;
  318.   typedef TAutoLongRef TAutoIntRef;
  319. #endif
  320.  
  321. //----------------------------------------------------------------------------
  322. // Attribute flags for automation symbols and command objects
  323. //
  324.  
  325. enum AutoSymFlag {
  326.   asAnyCommand     = 0x0017,  // any command: method, property get/set, build
  327.   asOleType        = 0x0007,  // method or property exposed for OLE
  328.   asMethod         = 0x0001,  // method     (same as OLE INVOKE_FUNC)
  329.   asGet            = 0x0002,  // returns property value (INVOKE_PROPERTYGET)
  330.   asIterator       = 0x000A,  // iterator property (_NewEnum)
  331.   asSet            = 0x0004,  // set property value     (INVOKE_PROPERTYSET)
  332.   asGetSet         = 0x0006,  // can get or set property(...GET + ...SET)
  333.   asBuild          = 0x0010,  // contructor command (unsupported by OLE 2.01)
  334.   asFactory        = 0x0020,  // for creating objects or class determination
  335.   asClass          = 0x0040,  // extension to another class symbol table
  336.   asArgument       = 0x0080,  // property returning an object
  337.   asNotTerminator  = 0x00FF,  // any symbol except terminator with class info
  338.  
  339.   asBindable       = 0x0400,  // sends OnChanged notification
  340.   asRequestEdit    = 0x0800,  // sends OnRequest edit before change
  341.   asDisplayBind    = 0x1000,  // user-display of bindable
  342.   asDefaultBind    = 0x2000,  // this property only is the default (redundant)
  343.   asHidden         = 0x4000,  // not visible to normal browsing
  344.   asPersistent     = 0x8000,  // property is persistent
  345. };
  346.  
  347. //
  348. // Automation datatypes and flags - same as OLE 2 definitions
  349.  
  350. //
  351. enum AutoDataType {
  352.   atVoid              = VT_EMPTY,     //  0x0000,   //  void
  353.   atNull              = VT_NULL,      //  0x0001,   //  SQL style Null
  354.   atShort             = VT_I2,        //  0x0002,   //  2 byte signed int
  355.   atLong              = VT_I4,        //  0x0003,   //  4 byte signed int
  356.   atFloat             = VT_R4,        //  0x0004,   //  4 byte real
  357.   atDouble            = VT_R8,        //  0x0005,   //  8 byte real
  358.   atCurrency          = VT_CY,        //  0x0006,   //  currency
  359.   atDatetime          = VT_DATE,      //  0x0007,   //  datetime as double
  360.   atString            = VT_BSTR,      //  0x0008,   //  String preceeded by length
  361.   atObject            = VT_DISPATCH,  //  0x0009,   //  IDispatch*
  362.   atError             = VT_ERROR,     //  0x000A,   //  SCODE
  363.   atBool              = VT_BOOL,      //  0x000B,   //  True=-1, False=0
  364.   atVariant           = VT_VARIANT,   //  0x000C,   //  VARIANT*
  365.   atUnknown           = VT_UNKNOWN,   //  0x000D,   //  IUnknown*
  366.   atByte              = VT_UI1,       //  0x0011,   //  byte, unsigned char
  367.   atArray             = VT_ARRAY,     //
  368.   atObjectDesc        = 0x001D,   //  object precursor state (internal use only)
  369.   atLoanedBSTR        = 0x001A,   //  BSTR owned by TUString (internal use only)
  370.   atTypeMask          = 0x001F,   //  base type code without bit flags
  371.   atOLE2Mask          = 0x601F,   //  type code with bit flags
  372. };
  373. const uint16 atSafeArray= 0x2000;
  374. const uint16 atByRef    = 0x4000;
  375. const uint16 atEnum     = 0x1000; // non-OLE, enumeration for data of a type
  376. const uint16 atAutoClass= 0x0800; // non-OLE, class object is a TAutoClass
  377.  
  378. //----------------------------------------------------------------------------
  379. // Automated class typeinfo flags - corresponding to OLE 2.02 definitions
  380. //    flags set in END_AUTOCLASS, END_AUTOAGGREGATE, END_AUTOEVENTCLASS macros
  381. //
  382.  
  383. //
  384. // Flags set on any autoclass, but apply only to enclosing coclass typeinfo.
  385. // Autoclasses with any of these bits set will be members of generated coclass.
  386. // These flags from all autoclasses are combined to form the coclass type flags
  387.  
  388. //
  389. const uint16 tfAppObject     =   1; // TYPEFLAG_FAPPOBJECT, set on COCLASS
  390. const uint16 tfCanCreate     =   2; // TYPEFLAG_FCANCREATE, set on COCLASS
  391. const uint16 tfLicensed      =   4; // TYPEFLAG_FLICENSED,  set on COCLASS
  392. const uint16 tfPredeclared   =   8; // TYPEFLAG_FPREDECLID, set on COCLASS
  393. const uint16 tfControl       =  32; // TYPEFLAG_FCONTROL,   set on COCLASS
  394. const uint16 tfCoClassXfer   =  tfAppObject|tfCanCreate|tfLicensed|tfControl|tfPredeclared;
  395.  
  396. //
  397. // Flags set on any autoclass, but used when class is a member of a coclass.
  398. // Autoclasses with any of these bits set will be members of generated coclass.
  399. // Flags from each class are set on the corresponding interfaces in the coclass
  400.  
  401. //
  402. const uint16 tfDefault      = (1<<12); // IMPLTYPEFLAG_FDEFAULT << 12
  403. const uint16 tfEventSource  = (2<<12); // IMPLTYPEFLAG_FSOURCE << 12
  404. const uint16 tfRestricted   = (4<<12); // IMPLTYPEFLAG_FRESTRICTED << 12
  405. const uint16 tfImplFlagXfer = (tfDefault | tfEventSource | tfRestricted);
  406.  
  407. //
  408. // Flags set on individual autoclasses, transferred to corresponding typeinfos
  409.  
  410. //
  411. const uint16 tfHidden        =  16;  // TYPEFLAG_FHIDDEN
  412. const uint16 tfNonextensible = 128;  // TYPEFLAG_FNONEXTENSIBLE
  413. const uint16 tfAutoClassMask =  tfHidden|tfNonextensible;
  414.  
  415. //
  416. // Flags defined by OLE, but not applicable to dispatch interfaces
  417.  
  418. //
  419. const uint16 tfDual          =  64;  // TYPEFLAG_FDUAL
  420. const uint16 tfAutomation    = 256;  // TYPEFLAG_FOLEAUTOMATION
  421.  
  422. //
  423. // Default typeflags value for autoclass not exposed as part of the coclass
  424.  
  425. //
  426. const uint16 tfNormal        =   0;  // automated classes not at app level
  427.  
  428. //
  429. // class TAutoSymbol
  430. // ~~~~~ ~~~~~~~~~~~
  431. // Symbol table element
  432. //
  433. struct TAutoSymbol {
  434.   TLocaleString Name;         // name of symbol, initially untranslated
  435.   TLocaleString Doc;          // documentation string, initially untranslated
  436.   uint32 Attr;                // attributes: enum AutoSymFlag, as???? (could be uint16)
  437.   union {
  438.     long  DispId;             // reserved dispatch ID, if not 0
  439.     short SymCount;           // asClass only: symbol count, 0 = uncounted yet
  440.     unsigned short TypeFlags; // class symbol only (terminator)
  441.   };
  442.   TAutoType* Type;                  // pointer to class/type/enum descriptor
  443.   union {
  444.     TAutoCommandBuild  Build;       // asAnyCommand only: address of command builder
  445.     TAutoIteratorBuild BuildIter;   // asIterator only: address of iterator builder
  446.     TAutoSymTypeConvert Convert;    // asFactory/asClass: function to perform cast
  447.     TAutoCommandBuildDtr BuildDtr;  // terminator only: destructor command builder
  448.     void*      DefaultArg;          // asArgument: default value, extends to 8 bytes
  449.   };
  450.   ulong HelpId;                     // help context ID, not for asArgument
  451.  
  452.   // Inline data member accessor functions
  453.   //
  454.   void         SetFlag(uint16 mask);
  455.   void         ClearFlag(uint16 mask);
  456.   bool         TestFlag(uint16 mask) const;
  457.   uint16       GetFlags() const;
  458.   bool         IsEnum() const;
  459.   bool         IsByRef() const;
  460.   bool         IsArray() const;
  461.   bool         IsIterator() const;
  462.   bool         IsTerminator() const;
  463.   uint16       GetDataType() const;
  464.   TAutoClass*  GetClass() const;
  465.   TAutoEnum*   GetEnum() const;
  466.  
  467.   // Inline static functions solely to provide type-safety initializing symbols
  468.   //
  469.   static TAutoCommandBuild InitTypeConvert(TAutoSymTypeConvert f);
  470.   static TAutoCommandBuild InitAutoIterator(TAutoIteratorBuild f);
  471.   static TAutoCommandBuild InitAutoDestructor(TAutoCommandBuildDtr f);
  472. };
  473.  
  474. //
  475. // struct TObjectDescriptor
  476. // ~~~~~~ ~~~~~~~~~~~~~~~~~
  477. // Precursor to TServedObject containing object info
  478. // NOTE: Cannot have a constructor and must limit to 8 bytes for TAutoVal union
  479. //
  480. struct TObjectDescBase {   // ONLY for use when storing in TAutoVal union
  481.   const void* Object;      // pointer to C++ object
  482.   TAutoClass* Class;       // class descriptor, contains typeinfo
  483.   const void* MostDerived() {
  484.     return NS_OCF::MostDerived(Object, Class->GetTypeInfo());
  485.   }
  486. };
  487.  
  488. // Double check size of TObjectDescBase
  489. //
  490. #if defined(BI_COMP_BORLANDC)
  491.   #if sizeof(TObjectDescBase) > 8
  492.     #error Sizeof TObjectDescBase must be 8 bytes - it's a TAutoVal union member
  493.   #endif
  494. #endif
  495.  
  496. //
  497. // struct TObjectDescriptor
  498. // ~~~~~~ ~~~~~~~~~~~~~~~~~
  499. struct TObjectDescriptor : public TObjectDescBase {
  500.   enum TDestruct     { // behavior when an automation helper is freed
  501.     Quiet = 0,         // automation object quietly goes away without notice
  502.     Delete = 1,        // automation object deletes the C++ object serviced
  503.     PostQuit = 2       // automation object posts a quit message to application
  504.   };
  505.   TDestruct Destruct;
  506.   TObjectDescriptor(const void* obj, TAutoClass& classobj,
  507.                     TObjectDescriptor::TDestruct destruct = Quiet)
  508.                     { Object = obj; Class = &classobj; Destruct = destruct; }
  509.   private:
  510.     TObjectDescriptor() {}    // uninitialized struct
  511.   friend class TAutoClass;    // restrict access to uninitialized constructor
  512.   friend class TAutoIterator;
  513. };
  514.  
  515. //
  516. // class TAutoVal
  517. // ~~~~~ ~~~~~~~~
  518. // Automation data element (same data as OLE/BASIC VARIANT)
  519. //
  520. // This class simply duplicates and adds access methods to the system VARIANT
  521. // Data members or virtual functions cannot be added.
  522. // We rely on the fact that we can cast a VARIANT safely to/from a TAutoVal.
  523. //
  524. class far TAutoVal {
  525.   public:
  526.  
  527.     // Default constructors/assignment operators/destructors
  528.     //
  529.     TAutoVal();
  530.     TAutoVal(const TAutoVal& src);
  531.     const TAutoVal& operator =(const TAutoVal& src);
  532.     ~TAutoVal();
  533.  
  534.     // Constructors to create a TAutoVal/VARIANT from a C++ type
  535.     //
  536.     TAutoVal(unsigned char      i){ *this = i; };
  537.     TAutoVal(signed char        i){ *this = i; };
  538.     TAutoVal(char               i){ *this = i; };
  539.     TAutoVal(unsigned char*     p){ *this = p; };
  540.     TAutoVal(signed char*       p){ *this = p; };
  541.     TAutoVal(char*              p){ *this = p; };
  542.     TAutoVal(int                i){ *this = i; };
  543.     TAutoVal(int*               p){ *this = p; };
  544.     TAutoVal(unsigned int       i){ *this = i; };
  545.     TAutoVal(unsigned int*      p){ *this = p; };
  546.     TAutoVal(unsigned short     i){ *this = i; };
  547.     TAutoVal(unsigned short*    p){ *this = p; };
  548.     TAutoVal(long               i){ *this = i; };
  549.     TAutoVal(long*              p){ *this = p; };
  550.     TAutoVal(unsigned long      i){ *this = i; };
  551.     TAutoVal(unsigned long*     p){ *this = p; };
  552.     TAutoVal(short              i){ *this = i; };
  553.     TAutoVal(short*             p){ *this = p; };
  554.     TAutoVal(float              i){ *this = i; };
  555.     TAutoVal(float*             p){ *this = p; };
  556.     TAutoVal(double             i){ *this = i; };
  557.     TAutoVal(double*            p){ *this = p; };
  558.     TAutoVal(TBool              i){ *this = i; };
  559.     TAutoVal(TBool*             p){ *this = p; };
  560. #if !defined(BI_UNIQUE_BOOL)
  561.     TAutoVal(TAutoBool          i){ *this = i; };
  562.     TAutoVal(TAutoBoolRef       p){ *this = p; };
  563. #endif
  564.     TAutoVal(const string&      s){ *this = s; };
  565.     TAutoVal(TAutoString        s){ *this = s; };
  566.     TAutoVal(TAutoCurrency      i){ *this = i; };
  567.     TAutoVal(TAutoCurrency*     p){ *this = p; };
  568.     TAutoVal(TAutoDate          i){ *this = i; };
  569.     TAutoVal(TAutoDate*         i){ *this = i; };
  570.     TAutoVal(IDispatch*       ifc){ *this = ifc; };
  571.     TAutoVal(IUnknown*        ifc){ *this = ifc; };
  572. #if defined(BI_PLAT_WIN32)
  573.     TAutoVal(IPictureDisp*    ifc){ *this = ifc; };
  574.     TAutoVal(IFontDisp*       ifc){ *this = ifc; };
  575. #endif
  576.     TAutoVal(VARIANT&           v){ *this = v; };
  577.     TAutoVal(const TNoArg&      n){ *this = n; };
  578.  
  579.     // Operators to extract a C++ type from a TAutoVal/VARIANT
  580.     //
  581.     operator unsigned char();
  582.     operator signed char();
  583.     operator char();
  584.     operator unsigned char*();
  585.     operator signed char*();
  586.     operator char*();
  587.     operator int();
  588.     operator int*();
  589.     operator unsigned int();
  590.     operator short();
  591.     operator short*();
  592.     operator unsigned short();
  593.     operator unsigned short*();
  594.     operator long();
  595.     operator long*();
  596.     operator unsigned long();
  597.     operator unsigned long*();
  598.     operator float();
  599.     operator float*();
  600.     operator double();
  601.     operator double*();
  602.     operator TBool();
  603.     operator TBool*();
  604. #if !defined(BI_UNIQUE_BOOL)
  605.     operator TAutoBool();
  606.     operator TAutoBoolRef();
  607. #endif
  608.     operator TAutoCurrency();
  609.     operator TAutoCurrency*();
  610.     operator TAutoDate();
  611.     operator TAutoDate*();
  612.     operator string();
  613.     operator TUString*();
  614.     operator TString();
  615.     operator TAutoString();
  616.     operator IUnknown*();
  617.     operator IDispatch*();
  618. #if defined(BI_PLAT_WIN32)
  619.     operator IPictureDisp*();
  620.     operator IFontDisp*();
  621.     operator IPictureDisp&();
  622.     operator IFontDisp&();
  623. #endif
  624.     operator IUnknown&();
  625.     operator IDispatch&();
  626.  
  627.     // Assignment operators to initialize a TAutoVal/VARIANT with the contents
  628.     // of a instance of a C++ type.
  629.     //
  630.     void operator =(unsigned char      i);
  631.     void operator =(signed char        i);
  632.     void operator =(char               i);
  633.     void operator =(unsigned char*     p);
  634.     void operator =(signed char*       p);
  635.     void operator =(char*              p);
  636.     void operator =(int                i);
  637.     void operator =(int*               p);
  638.     void operator =(unsigned int       i);
  639.     void operator =(unsigned int*      p);
  640.     void operator =(unsigned short     i);
  641.     void operator =(unsigned short*    p);
  642.     void operator =(long               i);
  643.     void operator =(long*              p);
  644.     void operator =(unsigned long      i);
  645.     void operator =(unsigned long*     p);
  646.     void operator =(short              i);
  647.     void operator =(short*             p);
  648.     void operator =(float              i);
  649.     void operator =(float*             p);
  650.     void operator =(double             i);
  651.     void operator =(double*            p);
  652.     void operator =(TBool              i);
  653.     void operator =(TBool*             p);
  654. #if !defined(BI_UNIQUE_BOOL)
  655.     void operator =(TAutoBool          i);
  656.     void operator =(TAutoBoolRef       p);
  657. #endif
  658.     void operator =(const string&      s);
  659.     void operator =(TAutoString        s);
  660.     void operator =(TAutoCurrency      i);
  661.     void operator =(TAutoCurrency*     p);
  662.     void operator =(TAutoDate          i);
  663.     void operator =(TAutoDate*         i);
  664.     void operator =(IUnknown*        ifc);
  665.     void operator =(IDispatch*       ifc);
  666. #if defined(BI_PLAT_WIN32)
  667.     void operator =(IPictureDisp*    ifc);
  668.     void operator =(IFontDisp*       ifc);
  669. #endif
  670.     void operator =(VARIANT&           v);
  671.     void operator =(TObjectDescriptor od);
  672.     void operator =(TAutoVoid           );
  673.     void operator =(const TNoArg&      n);
  674.  
  675.     // Query/Manipulate VARIANT object
  676.     //
  677.     int         GetDataType() const;   // Returns variant type
  678.     void        Init();                // Initializes VARIANT/TAutoVal to 0s
  679.     void        Clear();               // Free refs, set type to atVoid
  680.     void        Restore();             // Revert non-OLE changes to original types
  681.     void        Copy(const TAutoVal& copy);
  682.     HRESULT     ChangeType(VARTYPE type, TAutoVal* src = 0);
  683.     bool        IsRef() const;
  684.  
  685.     // Retrieve VARIANT object catering for VT_VARIANT|VT_BYREF
  686.     //
  687.     TAutoVal*   DereferenceVariant();
  688.  
  689.     void        SetLocale(TLocaleId);     // Associate locale with appropriate pointers
  690.     TLocaleId   GetLocale() const;        // Retrieve locale from appropriate pointers
  691.     TLangId     GetLanguage() const;      // Retrieve language from pointer types
  692.     TString     StrVal();                 // Returns internal string pointer if atString
  693.     bool        GetObjDesc(TObjectDescriptor&); // Return temp obj info or false
  694.     SAFEARRAY*  GetArray();               // Return array pointer, or 0
  695.     void*       SetByRef(AutoDataType);   // Set type, return pointer to data loc
  696.  
  697.   private:
  698.  
  699.     // The following members follow the layout of the actual VARIANT type
  700.     //
  701.     unsigned short vt;
  702.     unsigned short Reserved1;
  703.     unsigned short Reserved2;
  704.     unsigned short Reserved3;
  705.     union {
  706.       unsigned char bVal;             // VT_UI1
  707.       short         iVal;             // VT_I2
  708.       long          lVal;             // VT_I4
  709.       float         fltVal;           // VT_R4
  710.       double        dblVal;           // VT_R8
  711.       VARIANT_BOOL  boolVal;          // VT_BOOL
  712.       SCODE         scode;            // VT_ERROR
  713.       TAutoCurrency cyVal;            // VT_CY
  714.       DATE          date;             // VT_DATE
  715.       BSTR          bstrVal;          // VT_BSTR
  716.       IUnknown*     punkVal;          // VT_UNKNOWN
  717.       IDispatch*    pdispVal;         // VT_DISPATCH
  718.       SAFEARRAY* parray;              // VT_ARRAY
  719.       unsigned char* pbVal;           // VT_BYREF|VT_UI1
  720.       short        * piVal;           // VT_BYREF|VT_I2
  721.       long         * plVal;           // VT_BYREF|VT_I4
  722.       float        * pfltVal;         // VT_BYREF|VT_R4
  723.       double       * pdblVal;         // VT_BYREF|VT_R8
  724.       VARIANT_BOOL * pbool;           // VT_BYREF|VT_BOOL
  725.       SCODE        * pscode;          // VT_BYREF|VT_ERROR
  726.       TAutoCurrency* pcyVal;          // VT_BYREF|VT_CY
  727.       DATE         * pdate;           // VT_BYREF|VT_DATE
  728.       BSTR         * pbstrVal;        // VT_BYREF|VT_BSTR
  729.       IUnknown*    * ppunkVal;        // VT_BYREF|VT_UNKNOWN
  730.       IDispatch*   * ppdispVal;       // VT_BYREF|VT_DISPATCH
  731.       SAFEARRAY*   * pparray;         // VT_BYREF|VT_ARRAY
  732.       VARIANT      * pvarVal;         // VT_BYREF|VT_VARIANT
  733.       void         * byref;           // Generic ByRef
  734.  
  735.       // The following entries are enhancements to the VARIANT type allowing
  736.       // OCF to 'carry' additional information. NOTE: These members make it
  737.       // impractical to have TAutoVal derive from the VARIANT type.
  738.       //
  739.       struct {                       // Added locale info for BSTR/IDispatch
  740.         void* Val;
  741.         LCID      Locale;            // Unused 4 bytes for pointer types
  742.       } p;
  743.  
  744.       struct {                       // Added info when loaned BSTR ownership
  745.         BSTR      Val;
  746.         TUString* Holder;            // String holder sharing current BSTR
  747.       } s;
  748.  
  749.       TObjectDescBase ObjDesc;       // Temporary space for returning object
  750.     };
  751.  
  752.     void ConvRef(int type);
  753. };
  754.  
  755. // Check that TAutoVal is 'size-wise' VARIANT compatible
  756. //
  757. #if defined(BI_COMP_BORLANDC)
  758. # if sizeof(TAutoVal) != sizeof(VARIANT)
  759. #    Error Sizeof(TAutoVal) must match Sizeof(VARIANT)
  760. # endif
  761. #endif
  762.  
  763. //
  764. // class TAutoString
  765. // ~~~~~ ~~~~~~~~~~~
  766. // Based on reference counted TString with added automation functionality
  767. //
  768. class TAutoString : public TString {
  769.   public:
  770.     TAutoString(const char* s = 0) : TString(s) {}
  771. #if defined(BI_HAS_WCHAR)
  772.     TAutoString(const wchar_t* s)      : TString(s) {}
  773. #endif
  774.     TAutoString(BSTR s, bool loan)     : TString(s) {}
  775.     TAutoString(const string& s)       : TString(s) {}
  776.     TAutoString(TUString* s)           : TString(s) {}
  777.     TAutoString(TAutoVal& val)         : TString((TString)val) {}
  778.     TAutoString(const TAutoString& src) : TString(src.S) {++*S;}
  779.  
  780.     TAutoString& operator =(const char* s) {S = S->Assign(s); return *this;}
  781.     TAutoString& operator =(const TAutoString& s) {S = S->Assign(*s.S); return *this;}
  782.     TAutoString& operator =(char* s)           {S = S->Assign(s); return *this;}
  783. #if defined(BI_HAS_WCHAR)
  784.     TAutoString& operator =(const wchar_t* s)  {S = S->Assign(s); return *this;}
  785.     TAutoString& operator =(wchar_t* s)        {S = S->Assign(s); return *this;}
  786. #endif
  787.     TAutoString& operator =(TAutoVal& val)     {--*S; S = val; return *this;}
  788.  
  789.     static TAutoType ClassInfo;              // automation type code
  790. };
  791.  
  792. //
  793. // class TAutoStack
  794. // ~~~~~ ~~~~~~~~~~
  795. // Automation argument stack abstraction
  796. //
  797. class TAutoStack {
  798.   public:
  799.     enum {SetValue = -3};     // Special arg index for property set value
  800.     TAutoStack(DISPID dispid, VARIANT* stack, TLocaleId locale,
  801.                int argcount,
  802.                int namedcount, long* map, TServedObject* owner);
  803.    ~TAutoStack();
  804.     TAutoVal& operator[](int index);
  805.  
  806.     TAutoSymbol*   Symbol;      // Symbol of method/prop, args follow
  807.     int            CurrentArg;  // Index of last arg requested by operator[]
  808.     int            ArgCount;
  809.     int            ArgSymbolCount;
  810.     DISPID         DispId;
  811.     TLangId        LangId;
  812.     TServedObject* Owner;
  813.     long           ErrorCode;   // Set if TXAuto::xErrorStatus returned
  814.     const char*    ErrorMsg;    // Set if TXAuto::xErrorStatus returned
  815.  
  816.   protected:
  817.     int            NamedCount;
  818.     long*          NamedIds;
  819.     TAutoVal       Default;
  820.     TAutoVal*      Stack;
  821. };
  822.  
  823. struct TAutoTransfer;              // Persistence transfer parameter structure
  824.  
  825. //
  826. // class TAutoCommand
  827. // ~~~~~ ~~~~~~~~~~~~
  828. // Automation abstract base class for command objects
  829. //
  830. class TAutoCommand {
  831.   public:
  832.     TAutoCommand(int attr);          // Construtor called from derived classes
  833.  
  834.     virtual ~TAutoCommand() {}
  835.     virtual TAutoCommand* Undo();             // generate command for undo stack
  836.     virtual int           Record(TAutoStack& q); // record command and arguments
  837.     virtual TAutoCommand& Invoke();           // invoke all command processing
  838.     virtual bool          Validate();         // validate parameters
  839.     virtual void          Execute();          // perform action on C++ object
  840.     virtual long          Report();           // check result of execution
  841.     virtual void          Return(TAutoVal& v);// convert return value to variant
  842.     virtual void          Transfer(TAutoTransfer& x); // stream data in or out
  843.             void          Fail(TXAuto::TError);// throw designated exception
  844.  
  845.     // Non-virtual hook functions
  846.     //
  847.     typedef const char* (*TErrorMsgHook)(long errCode);
  848.     static TErrorMsgHook SetErrorMsgHook(TErrorMsgHook callback);
  849.  
  850.     typedef bool (*TCommandHook)(TAutoCommand& cmdObj);
  851.     static TCommandHook SetCommandHook(TCommandHook callback);
  852.  
  853.     // inline data member accessor functions
  854.     //
  855.     static const char* LookupError(long errCode);
  856.     void SetFlag(int mask);
  857.     void ClearFlag(int mask);
  858.     bool TestFlag(int mask);
  859.     bool IsPropSet();
  860.     TAutoSymbol* GetSymbol();
  861.     void SetSymbol(TAutoSymbol* sym);
  862.  
  863.   protected:
  864.     TAutoSymbol* Symbol;      // Symbol entry generating this command
  865.     int          Attr;        // Attribute and state flags, asXXXXXX
  866. };
  867.     extern TAutoCommand::TErrorMsgHook TAutoCommand_ErrorLookup;
  868.     extern TAutoCommand::TCommandHook  TAutoCommand_InvokeHook;
  869.  
  870. //
  871. // Build function for application Quit command implementation
  872. //
  873. TAutoCommand* AutoQuitBuild(ObjectPtr obj, int attr, TAutoStack& args);
  874.  
  875. //----------------------------------------------------------------------------
  876. // TAutoEnum - automation enumeration descriptor
  877. //
  878.  
  879. template <class T> struct TAutoEnumVal {
  880.   TLocaleString Name;         // Name of symbol, enumeration text
  881.   T             Val;          // Enumeration internal value
  882. };
  883.  
  884. class TAutoEnum : public TAutoType {
  885.   public:
  886.     virtual bool Convert(TAutoVal& txtVal, TAutoVal& numVal) = 0;
  887.     virtual bool Convert(TAutoVal& numVal, TLangId langId) = 0;
  888.  
  889.   protected:
  890.     TAutoEnum(int count, int type);
  891.     int Count;              // length of this symbol table
  892. };
  893.  
  894. template <class T> class TAutoEnumT : public TAutoEnum {
  895.   public:
  896.     TAutoEnumT(TAutoEnumVal<T>* table, int symcount, int type);
  897.     bool Convert(TAutoVal& txtVal, TAutoVal& numVal);
  898.     bool Convert(TAutoVal& numVal, TLangId langId);
  899.  
  900.   protected:
  901.     TAutoEnumVal<T>* Table; // pointer to array of symbol entries
  902. };
  903.  
  904. //____________________________________________________________________________
  905. //
  906. // TAutoCreator - Object responsible for creating automation COM object
  907. //____________________________________________________________________________
  908.  
  909. class TAutoCreator {
  910.   public:
  911.     TAutoCreator() {}
  912.     virtual TUnknown*  CreateObject(TObjectDescriptor objDesc,
  913.                                     IUnknown* outer = 0) = 0;
  914.     virtual IDispatch* CreateDispatch(TObjectDescriptor objDesc,
  915.                                       IUnknown* outer = 0) = 0;
  916.     virtual void       Attach(TServedObject& obj) {}
  917.     virtual void       Detach(TServedObject& obj) {}
  918. };
  919.  
  920. class TServedObjectCreator : public TAutoCreator {
  921.   public:
  922.     TServedObjectCreator(TAppDescriptor& appDesc);
  923.     TUnknown*  CreateObject(TObjectDescriptor objDesc, IUnknown* outer = 0);
  924.     IDispatch* CreateDispatch(TObjectDescriptor objDesc, IUnknown* outer = 0);
  925.     void       Attach(TServedObject& obj);
  926.     void       Detach(TServedObject& obj);
  927.  
  928.     TAppDescriptor& AppDesc;
  929.     TServedObject* AppObject;
  930.  
  931.   private:
  932.     int ObjCount;
  933.  
  934.   friend class TServedObject;
  935. };
  936.  
  937. class _ICLASS TDispatch;
  938.  
  939. class TDispatchCreator : public TAutoCreator {
  940.   public:
  941.     TDispatchCreator() {}
  942.     TUnknown*  CreateObject(TObjectDescriptor objDesc, IUnknown* outer = 0);
  943.     IDispatch* CreateDispatch(TObjectDescriptor objDesc, IUnknown* outer = 0);
  944. };
  945.  
  946. //----------------------------------------------------------------------------
  947. // TServedObject - OLE object exposed for automated access of internal object
  948. //
  949.  
  950. DECLARE_COMBASES2(TServedCOM, IDispatch, ITypeInfo)
  951.  
  952. class _ICLASS TServedObject : public TServedCOM {
  953.   public:
  954.     TServedObject(TObjectDescriptor& obj, TServedObjectCreator& creator,
  955.                                           IUnknown* outer=0);
  956.    ~TServedObject();
  957.     TServedObject* GetAppObject() {return Creator.AppObject;}
  958.     TServedObjectCreator& GetCreator() {return Creator;}
  959.     void* Object;          // pointer to C++ object instance, 0 if deleted
  960.     const void* RootObject;  // pointer to object of most derived class
  961.     TAutoClass*     Class;       // class of which object is an instance
  962.     TServedObjectCreator& Creator;
  963.     operator IDispatch*();
  964.     TLangId ReqLang;             // language requested by caller
  965.     TObjectDescriptor::TDestruct Destruct;  // what to do with C++ object
  966.  
  967.     // Object reference & lifetime managment
  968.     // For internal OCF use only
  969.     //
  970.     ulong   _IFUNC AddRef() {return GetOuter()->AddRef();}
  971.     ulong   _IFUNC Release() {return GetOuter()->Release();}
  972.     HRESULT _IFUNC QueryInterface(const GUID far& iid, void*far* iface)
  973.                      {return GetOuter()->QueryInterface(iid, iface);}
  974.  
  975.   protected:
  976.     // TUnknown overrides
  977.     //
  978.     HRESULT      QueryObject(const IID far& iid, void** iface);
  979.  
  980.   private:
  981.     IID                   iidEvent;
  982.     TServedObject*        Next;
  983.     TServedObject**   Prev;
  984.     // need to access local LANGID for typeinfo, either as member or as global
  985.  
  986.     // IDispatch implementation
  987.     HRESULT _IFUNC GetTypeInfoCount(unsigned int* pctinfo);
  988.     HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
  989.                                ITypeInfo** pptinfo);
  990.     HRESULT _IFUNC GetIDsOfNames(const IID far& riid, OLECHAR** rgszNames,
  991.                                  uint cNames, LCID lcid,
  992.                                  DISPID* rgdispid);
  993.     HRESULT _IFUNC Invoke(DISPID dispidMember, const IID far& riid, LCID lcid,
  994.                                  unsigned short wFlags,
  995.                                  DISPPARAMS* pdispparams,
  996.                                  VARIANT* pvarResult,
  997.                                  EXCEPINFO* pexcepinfo,
  998.                                  unsigned int* puArgErr);
  999.  
  1000.     // ITypeInfo implementation
  1001.     //
  1002.     HRESULT _IFUNC GetTypeAttr(TYPEATTR** pptypeattr);
  1003.     HRESULT _IFUNC GetTypeComp(ITypeComp** pptcomp);
  1004.     HRESULT _IFUNC GetFuncDesc(unsigned int index, FUNCDESC** ppfuncdesc);
  1005.     HRESULT _IFUNC GetVarDesc(unsigned int index, VARDESC** ppvardesc);
  1006.     HRESULT _IFUNC GetNames(MEMBERID memid, BSTR* rgbstrNames,
  1007.                             unsigned int cMaxNames,
  1008.                             unsigned int* pcNames);
  1009.     HRESULT _IFUNC GetRefTypeOfImplType(unsigned int index, HREFTYPE* phreftype);
  1010.     HRESULT _IFUNC GetImplTypeFlags(unsigned int index, int* pimpltypeflags);
  1011.     HRESULT _IFUNC GetIDsOfNames(OLECHAR** rgszNames,
  1012.                                  unsigned int cNames,
  1013.                                  MEMBERID* rgmemid);
  1014.     HRESULT _IFUNC Invoke(void* pvInstance, MEMBERID memid,
  1015.                           unsigned short wFlags,
  1016.                           DISPPARAMS far *pdispparams,
  1017.                           VARIANT far *pvarResult,
  1018.                           EXCEPINFO far *pexcepinfo,
  1019.                           unsigned int far *puArgErr);
  1020.     HRESULT _IFUNC GetDocumentation(MEMBERID memid,
  1021.                                     BSTR* pbstrName,
  1022.                                     BSTR* pbstrDocString,
  1023.                                     ulong* pdwHelpContext,
  1024.                                     BSTR* pbstrHelpFile);
  1025.     HRESULT _IFUNC GetDllEntry(MEMBERID memid, INVOKEKIND invkind,
  1026.                                BSTR* pbstrDllName,
  1027.                                BSTR* pbstrName,
  1028.                                unsigned short* pwOrdinal);
  1029.     HRESULT _IFUNC GetRefTypeInfo(HREFTYPE hreftype,
  1030.                                   ITypeInfo** pptinfo);
  1031.     HRESULT _IFUNC AddressOfMember(MEMBERID memid, INVOKEKIND invkind,
  1032.                                    void** ppv);
  1033.     HRESULT _IFUNC CreateInstance(IUnknown* punkOuter, const IID far& riid,
  1034.                                   void** ppvObj);
  1035.     HRESULT _IFUNC GetMops(MEMBERID memid, BSTR* pbstrMops);
  1036.     HRESULT _IFUNC GetContainingTypeLib(ITypeLib** pptlib,
  1037.                                         uint* pindex);
  1038.     void _IFUNC ReleaseTypeAttr(TYPEATTR* ptypeattr);
  1039.     void _IFUNC ReleaseFuncDesc(FUNCDESC* pfuncdesc);
  1040.     void _IFUNC ReleaseVarDesc(VARDESC* pvardesc);
  1041.     HRESULT _IFUNC GetFuncDocFromIndex(unsigned index,
  1042.                                        BSTR* retName, BSTR* retDoc,
  1043.                                        ulong* retHelpContext,
  1044.                                        BSTR* retHelpFile);
  1045.     // GetVarDocFromIndex and GetDocFromSym are used to by WriteTypeLib to make
  1046.     // type libraries
  1047.     HRESULT _IFUNC GetVarDocFromIndex(unsigned index,
  1048.                                       BSTR* retName, BSTR* retDoc,
  1049.                                       ulong* retHelpContext,
  1050.                                       BSTR* retHelpFile);
  1051.     HRESULT _IFUNC GetDocFromSym(TAutoSymbol* sym,
  1052.                                  BSTR* retName, BSTR* retDoc,
  1053.                                  ulong* retHelpContext,
  1054.                                  BSTR* retHelpFile);
  1055.     friend class _ICLASS TAppDescriptor;   // access to Next,Prev
  1056.     friend class _ICLASS TOcxView;         // access to QueryObject
  1057.     friend class _ICLASS TOcControl;       // access to QueryObject
  1058. };
  1059.  
  1060. //----------------------------------------------------------------------------
  1061. // TDispatch - lightweight IDispatch implementation for automation controllers
  1062. //
  1063.  
  1064. DECLARE_COMBASES1(TDispatchCOM, IDispatch)
  1065.  
  1066. class _ICLASS TDispatch : public TDispatchCOM {
  1067.   public:
  1068.     TDispatch(const TObjectDescriptor& obj, IUnknown* outer = 0);
  1069.     void*        Object;      // pointer to C++ object instance, 0 if deleted
  1070.     TAutoClass*  Class;       // class of which object is an instance
  1071.     void InvalidateObject() {Object = 0;}
  1072.     operator IDispatch*();
  1073.   private:
  1074.     // IDispatch implementation
  1075.     HRESULT _IFUNC GetTypeInfoCount(unsigned int* pctinfo);
  1076.     HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
  1077.                                ITypeInfo** pptinfo);
  1078.     HRESULT _IFUNC GetIDsOfNames(const IID far& riid, OLECHAR** rgszNames,
  1079.                                  unsigned int cNames, LCID lcid,
  1080.                                  DISPID* rgdispid);
  1081.     HRESULT _IFUNC Invoke(DISPID dispidMember, const IID far& riid, LCID lcid,
  1082.                                  unsigned short wFlags,
  1083.                                  DISPPARAMS* pdispparams,
  1084.                                  VARIANT* pvarResult,
  1085.                                  EXCEPINFO* pexcepinfo,
  1086.                                  unsigned int* puArgErr);
  1087. };
  1088.  
  1089. //----------------------------------------------------------------------------
  1090. // TAutoObject - holders for C++ object pointers for automation conversions
  1091. //
  1092.  
  1093. template<class T>
  1094. class TAutoObject {
  1095.   public:
  1096.     void operator=(IDispatch& dp);
  1097.     void operator=(T* p) {P=p;}
  1098.     void operator=(T& r) {P=&r;}
  1099.     T& operator*() {return *P;}
  1100.     operator TObjectDescriptor() {return TObjectDescriptor(P, T::ClassInfo);}
  1101.     TAutoObject() : P(0) {}
  1102.     TAutoObject(T* p) {P=p;}
  1103.     TAutoObject(T& r) {P=&r;}
  1104.     TAutoObject(IDispatch& dr);
  1105.     operator T*() {return P;}
  1106.     operator T&() {return *P;}
  1107.   protected:
  1108.     T* P;
  1109.     T F();// only purpose to remove const for typeid incase T is a const class
  1110. };
  1111.  
  1112. template<class T>
  1113. TAutoObject<T>::TAutoObject(IDispatch& ifc)
  1114. {
  1115.   TServedObject* obj;
  1116.   if (ifc.QueryInterface(IID_TServedObject, (void**)&obj) != 0)
  1117.     throw TXAuto(TXAuto::xForeignIDispatch);
  1118.   P = (T*)DynamicCast(obj->Object, obj->Class->GetTypeInfo(), typeid(T));
  1119.   if (!P)
  1120.     throw TXAuto(TXAuto::xTypeMismatch);
  1121. }
  1122.  
  1123. template<class T> void
  1124. TAutoObject<T>::operator=(IDispatch& ifc)
  1125. {
  1126.   TServedObject* obj;
  1127.   if (ifc.QueryInterface(IID_TServedObject, (void**)&obj) != 0)
  1128.     throw TXAuto(TXAuto::xForeignIDispatch);
  1129.   P = (T*)DynamicCast(obj->Object, obj->Class->GetTypeInfo(), typeid(T));
  1130.   if (!P)
  1131.     throw TXAuto(TXAuto::xTypeMismatch);
  1132. }
  1133.  
  1134. template<class T>      // for returning objects only, no IDispatch constructor
  1135. class TAutoObjectDelete : public TAutoObject<T>{
  1136.   public:
  1137.     void operator=(T* p) {P=p;}
  1138.     void operator=(T& r) {P=&r;}
  1139.     TAutoObjectDelete()     : TAutoObject<T>() {}
  1140.     TAutoObjectDelete(T* p) : TAutoObject<T>(p) {}
  1141.     TAutoObjectDelete(T& r) : TAutoObject<T>(r) {}
  1142.     operator TObjectDescriptor()
  1143.         {return TObjectDescriptor(P,T::ClassInfo, TObjectDescriptor::Delete);}
  1144. };
  1145.  
  1146. template<class T>      // for returning objects by value
  1147. class TAutoObjectByVal : public TAutoObjectDelete<T> {
  1148.   public:
  1149.     void operator=(T o) {P=new T(o);}
  1150.     TAutoObjectByVal() : TAutoObjectDelete<T>() {}
  1151.     TAutoObjectByVal(T o) : TAutoObjectDelete<T>(new T(o)) {}
  1152. };
  1153.  
  1154. //----------------------------------------------------------------------------
  1155. // TAutoIterator - automation collection iterator
  1156. //
  1157.  
  1158.  
  1159. class TAutoIterator : public IEnumVARIANT {
  1160.   public:
  1161.     // IEnumVARIANT implementation
  1162.     HRESULT       _IFUNC QueryInterface(const GUID far& iid, void*far* pif);
  1163.     unsigned long _IFUNC AddRef();
  1164.     unsigned long _IFUNC Release();
  1165.     HRESULT _IFUNC Next(unsigned long count, VARIANT* retvals,
  1166.                         unsigned long* retcount);
  1167.     HRESULT _IFUNC Skip(unsigned long count);
  1168.     HRESULT _IFUNC Reset();
  1169.     HRESULT _IFUNC Clone(IEnumVARIANT** retiter);
  1170.  
  1171.     // specific implementation required by derived classes
  1172.     virtual void           Init()=0;   // reset to first item
  1173.     virtual bool           Test()=0;   // test if item exists
  1174.     virtual void           Step()=0;   // advance to next item
  1175.     virtual void           Return(TAutoVal& v)=0;// convert item to variant
  1176.     virtual TAutoIterator* Copy()=0;   // return copy of iterator
  1177.  
  1178.     // inline data member accessor functions
  1179.     TAutoSymbol* GetSymbol();
  1180.     void SetSymbol(TAutoSymbol* sym);
  1181.     operator IUnknown*();     // essentially a quick QueryInterface
  1182.  
  1183.     virtual ~TAutoIterator();
  1184.     TAutoClass* Class;
  1185.   protected:
  1186.     TAutoSymbol* Symbol;      // symbol entry generating this command
  1187.     TAutoCreator& Creator;    // object to create returned automation objects
  1188.     IUnknown* Owner;          // Release() must be called on destruction
  1189.     unsigned RefCnt;
  1190.     TLangId Lang;
  1191.     TAutoIterator(TAutoCreator& creator, IUnknown* owner, TLangId lang); // called from derived
  1192.     TAutoIterator(TAutoIterator& copy);  // copy constructor for base class
  1193.   };
  1194.  
  1195. //____________________________________________________________________________
  1196. //
  1197. // TAutoProxy - client C access proxy, base class
  1198. //____________________________________________________________________________
  1199.  
  1200. enum AutoCallFlag {
  1201.   acMethod         = 0x0001,  // method call, same as OLE2
  1202.   acPropGet        = 0x0002,  // returns property value, same as OLE2
  1203.   acPropSet        = 0x0004,  // set property value, same as OLE2
  1204.   acVoidRet        = 0x8000,  // pass NULL for return variant, not OLE2 flag
  1205. };
  1206.  
  1207. // TAutoProxyArgs is the base class of TAutoArgs. The logic used within
  1208. // TAutoProxyArgs makes certain assumption involving TAutoArgs.
  1209. //
  1210. class TAutoProxyArgs {
  1211.   protected:
  1212.     TAutoProxyArgs(int cnt) : Count(cnt) {}
  1213.    ~TAutoProxyArgs();
  1214.  
  1215.   public:
  1216.     // The following operators assume that if one skips this object, an
  1217.     // array of TAutoVal/VARIANT object follows..
  1218.     //
  1219.     operator  TAutoVal&()    {return *(TAutoVal*)(this+1);}
  1220.     operator  VARIANT* ()    {return  (VARIANT* )(this+1);}
  1221.     operator  unsigned int() {return Count;}
  1222.     TAutoVal& operator[](int index);
  1223.  
  1224.   private:
  1225.     int       Count;
  1226. };
  1227.  
  1228. // class TAutoArgs
  1229. // ~~~~~~~~~~~~~~~
  1230. // The first TAutoVal item of TAutoArgs holds the return value. Items at
  1231. // indices 1 through N+1 represent the first, second, third ... paramters.
  1232. // Of course, these parameters are optional.
  1233. //
  1234. template <int N>
  1235. struct TAutoArgs : public TAutoProxyArgs {
  1236.   TAutoVal Args[N+1];
  1237.   TAutoArgs() : TAutoProxyArgs(N) {}
  1238. };
  1239.  
  1240.  
  1241. // class TAutoProxy
  1242. // ~~~~~ ~~~~~~~~~~
  1243. //
  1244. class TAutoProxy {
  1245.   public:
  1246.    ~TAutoProxy();
  1247.  
  1248.     // Attach to [Detatch from] a dispatch interface
  1249.     //
  1250.     void        Bind(IUnknown* obj);
  1251.     void        Bind(IUnknown& obj);
  1252.     void        Bind(const GUID& guid);
  1253.     void        Bind(const char* progid);
  1254.     void        Bind(TAutoVal& val);
  1255.     void        Bind(IDispatch* obj);
  1256.     void        Bind(IDispatch& obj);
  1257.     void        Unbind(bool release = true);
  1258.  
  1259.     // Check/Querry binding
  1260.     //
  1261.     void        MustBeBound();
  1262.     bool        IsBound()  {return ToBool(That != 0);}
  1263.  
  1264.     // Check it there's a running copy of an object which supports IDispatch
  1265.     //
  1266.     static IDispatch*  GetObject(const char* progid);
  1267.  
  1268.     // Locale support
  1269.     //
  1270.     void        SetLang(TLangId lang) {Lang = lang;}
  1271.  
  1272.     // Access to dispatch interface
  1273.     //
  1274.     operator    IDispatch*();
  1275.     operator    IDispatch&();
  1276.  
  1277.     // Retrieve dispId
  1278.     //
  1279.     long        Lookup(const long id) {return id;}
  1280.     long        Lookup(const char* name);
  1281.     void        Lookup(const char* names, long* ids, unsigned count);
  1282.  
  1283.   protected:
  1284.     TAutoProxy(TLangId lang) : That(0), Lang(lang) {}
  1285.  
  1286.     // Invoke (IDispatch::Invoke)
  1287.     //
  1288.     TAutoVal&   Invoke(uint16 attr, TAutoProxyArgs& args, long* ids, unsigned named=0);
  1289.  
  1290.     IDispatch*  That;
  1291.     TLangId     Lang;
  1292. };
  1293.  
  1294. struct TAutoDispId {
  1295.   TAutoDispId(TAutoProxy* prx, const char* name) : Id(prx->Lookup(name)) {}
  1296.   TAutoDispId(TAutoProxy*, long id) : Id(id) {}
  1297.   operator long*()    {return &Id;}
  1298.   operator unsigned() {return   0;}
  1299.  
  1300.   long     Id;
  1301. };
  1302.  
  1303. template <int N> struct TAutoDispIds {
  1304.   TAutoDispIds(TAutoProxy* prx, const char* names) {prx->Lookup(names, Ids);}
  1305.   long Ids[N+1];
  1306.   operator long*()    {return Ids;}
  1307.   operator unsigned() {return N;}
  1308. };
  1309.  
  1310. class TAutoEnumeratorBase {
  1311.   public:
  1312.     void Bind(TAutoVal& val);
  1313.     void Unbind()   { if (Iterator) Iterator->Release(); Iterator=0; Clear();}
  1314.     bool Step();
  1315.     void Clear()      { Current.Clear(); }
  1316.     bool IsValid()    { return Current.GetDataType() != atVoid; }
  1317.     void Object(TAutoProxy& prx) { prx.Bind(Current); }
  1318.     void operator =(const TAutoEnumeratorBase& copy);
  1319.    ~TAutoEnumeratorBase() { Unbind(); }
  1320.   protected:
  1321.     TAutoEnumeratorBase() : Iterator(0) {Current = TAutoVoid();}
  1322.     TAutoEnumeratorBase(const TAutoEnumeratorBase& copy);
  1323.     IEnumVARIANT*     Iterator;
  1324.     TAutoVal          Current;
  1325. };
  1326.  
  1327. template <class T>
  1328. class TAutoEnumerator : public TAutoEnumeratorBase {
  1329.   public:
  1330.     TAutoEnumerator() : TAutoEnumeratorBase() {}
  1331.     TAutoEnumerator(const TAutoEnumerator<T>& cpy) : TAutoEnumeratorBase(cpy) {}
  1332.     void Value(T& v);
  1333.     operator T();
  1334. };
  1335.  
  1336. #if defined(BI_NAMESPACE)
  1337. } // namespace OCF
  1338. #endif
  1339.  
  1340. //____________________________________________________________________________
  1341. //
  1342. // Inline implementations for automation controller
  1343. //____________________________________________________________________________
  1344.  
  1345. //
  1346. //
  1347. inline TAutoVal& TAutoProxyArgs::operator[](int index)
  1348. {
  1349.   // NOTE: It's OK to use Count as subscript since there's always one
  1350.   //       addition TAutoVal/VARIANT for the return value.
  1351.   //
  1352.   PRECONDITION(index <= Count);
  1353.  
  1354.   // NOTE: The logic below takes care of the difference in the C and
  1355.   //       Automation calling conventions.
  1356.   //
  1357.   return *((TAutoVal*)(this+1)+(index ? Count+1-index : 0));
  1358. }
  1359.  
  1360. //
  1361. //
  1362. inline TAutoProxy::operator IDispatch&()
  1363. {
  1364.   // Following conditional avoid function call overhead - specially since
  1365.   // method is inline
  1366.   //
  1367.   if (!That)
  1368.     MustBeBound();
  1369.   return *That;
  1370. }
  1371.  
  1372. //
  1373. //
  1374. inline TAutoProxy::operator IDispatch*()
  1375. {
  1376.   if (That)
  1377.     That->AddRef();
  1378.   return That;
  1379. }
  1380.  
  1381. //
  1382. //
  1383. inline void TAutoProxy::Unbind(bool release)
  1384. {
  1385.   if (release && That)
  1386.     That->Release();
  1387.   That = 0;
  1388. }
  1389.  
  1390. //
  1391. //
  1392. inline TAutoProxy::~TAutoProxy()
  1393. {
  1394.   Unbind();
  1395. }
  1396.  
  1397. inline void TAutoEnumerator<short>::Value(short& v) { v = Current; }
  1398. inline void TAutoEnumerator<long>::Value(long& v)   { v = Current; }
  1399. inline void TAutoEnumerator<bool>::Value(bool& v)   { v = Current; }
  1400. inline void TAutoEnumerator<TAutoString>::Value(TAutoString& v)
  1401.                                                     { v = Current; }
  1402.  
  1403. inline TAutoEnumerator<short>::operator short() { return (short)Current; }
  1404. inline TAutoEnumerator<long>::operator long()   { return (long)Current; }
  1405. inline TAutoEnumerator<bool>::operator bool()   { return (bool)Current; }
  1406. inline TAutoEnumerator<TAutoString>::operator TAutoString()
  1407.                                                 { return (TAutoString)Current; }
  1408. //____________________________________________________________________________
  1409. //
  1410. // Inline implementations for automation server - part 1
  1411. //____________________________________________________________________________
  1412.  
  1413. // TAutoClass inlines
  1414.  
  1415. inline TAutoSymbol* TAutoClass::GetTable() const {
  1416.   return Table;
  1417. }
  1418. inline TAutoSymbol* TAutoClass::GetClassSymbol() const {
  1419.   return ClassSymbol;
  1420. }
  1421. inline TAutoCommandBuildDtr TAutoClass::GetDestructor() const {
  1422.   return ClassSymbol->BuildDtr;
  1423. }
  1424. inline const typeinfo&  TAutoClass::GetTypeInfo() const {
  1425.   return TypeInfo;
  1426. }
  1427. inline const char* TAutoClass::GetName(TLangId id) const {
  1428.   return ClassSymbol->Name.Translate(id);
  1429. }
  1430. inline const char* TAutoClass::GetDoc (TLangId id) const {
  1431.   return ClassSymbol->Doc.Translate(id);
  1432. }
  1433. inline unsigned long TAutoClass::GetHelpId() const {
  1434.   return ClassSymbol->HelpId;
  1435. }
  1436. inline unsigned short TAutoClass::GetTypeFlags() const {
  1437.   return ClassSymbol->TypeFlags & tfAutoClassMask;
  1438. }
  1439. inline int TAutoClass::GetImplTypeFlags() const {
  1440.   return ClassSymbol->TypeFlags>>12;
  1441. }
  1442. inline unsigned short TAutoClass::GetCoClassFlags() const {
  1443.   return ClassSymbol->TypeFlags & tfCoClassXfer;
  1444. }
  1445. inline TAggregator TAutoClass::GetAggregator() const {
  1446.   return Aggregator;
  1447. }
  1448. inline IUnknown& TAutoClass::Aggregate(ObjectPtr obj, TUnknown& inner) {
  1449.   return obj && Aggregator ? Aggregator(obj, inner) : (IUnknown&)inner;
  1450. }
  1451.  
  1452. //____________________________________________________________________________
  1453.  
  1454. // TAutoSymbol inlines
  1455.  
  1456. inline void TAutoSymbol::SetFlag(uint16 mask) {
  1457.  Attr |= mask;
  1458. }
  1459. inline void TAutoSymbol::ClearFlag(uint16 mask) {
  1460.   Attr &= uint16(~mask);
  1461. }
  1462. inline bool TAutoSymbol::TestFlag(uint16 mask) const {
  1463.   return (Attr&mask)? true : false;
  1464. }
  1465. inline uint16 TAutoSymbol::GetFlags() const {
  1466.   return (uint16)Attr;
  1467. }
  1468. inline bool TAutoSymbol::IsEnum() const {
  1469.   return (Type->GetType() & atEnum)? true : false;
  1470. }
  1471. inline bool TAutoSymbol::IsByRef() const {
  1472.   return (Type->GetType() & atByRef)? true:false;
  1473. }
  1474. inline bool TAutoSymbol::IsArray() const {
  1475.   return (Type->GetType() & atSafeArray)? true : false;
  1476. }
  1477. inline bool TAutoSymbol::IsIterator() const {
  1478.   return ((Attr&asIterator)==asIterator) ? true : false;
  1479. }
  1480. inline bool TAutoSymbol::IsTerminator() const {
  1481.   return ((Attr & asNotTerminator)== 0) ? true : false;
  1482. }
  1483. inline uint16 TAutoSymbol::GetDataType() const {
  1484.   return uint16(Type->GetType() & atTypeMask);
  1485. }
  1486. inline TAutoClass* TAutoSymbol::GetClass() const {
  1487.   return (Type->GetType() & atAutoClass)? (TAutoClass*)Type : 0;
  1488. }
  1489. inline TAutoEnum* TAutoSymbol::GetEnum() const {
  1490.   return (Type->GetType() & atEnum) ? (TAutoEnum*)Type : 0;
  1491. }
  1492. inline TAutoCommandBuild TAutoSymbol::InitTypeConvert(TAutoSymTypeConvert f)
  1493.                                          { return (TAutoCommandBuild)f;}
  1494. inline TAutoCommandBuild TAutoSymbol::InitAutoIterator(TAutoIteratorBuild f)
  1495.                                          { return (TAutoCommandBuild)f;}
  1496. inline TAutoCommandBuild TAutoSymbol::InitAutoDestructor(TAutoCommandBuildDtr f)
  1497.                                          { return (TAutoCommandBuild)f;}
  1498. //____________________________________________________________________________
  1499.  
  1500. // TAutoVal inlines
  1501.  
  1502. //
  1503. //
  1504. inline TAutoVal::TAutoVal()
  1505. {
  1506.   Init();
  1507. }
  1508.  
  1509. //
  1510. //
  1511. inline TAutoVal::~TAutoVal()
  1512. {
  1513.   Clear();
  1514. }
  1515.  
  1516. //
  1517. //
  1518. inline TAutoVal::TAutoVal(const TAutoVal& src)
  1519. {
  1520.   Init();
  1521.   ::VariantCopy((VARIANT*)this, (VARIANT*)&src);
  1522. }
  1523.  
  1524. //
  1525. //
  1526. inline const TAutoVal& TAutoVal::operator=(const TAutoVal& src)
  1527. {
  1528.   // NOTE: 'VariantCopy' takes care of 'freeing' the destination
  1529.   //
  1530.   ::VariantCopy((VARIANT*)this, (VARIANT*)&src);
  1531.   return *this;
  1532. }
  1533.  
  1534. inline TAutoVal::operator unsigned long(){return (unsigned long)operator long();}
  1535. #if (MAXINT==MAXSHORT)
  1536. inline TAutoVal::operator int()          {return operator short();}
  1537. inline TAutoVal::operator unsigned int() {return operator unsigned short();}
  1538. inline TAutoVal::operator int*()         {return (int*)operator short*();}
  1539. #else
  1540. inline TAutoVal::operator int()          {return operator long(); }
  1541. inline TAutoVal::operator unsigned int() {return (unsigned long)(long)*this;}
  1542. inline TAutoVal::operator int*()         {return (int*)operator long*();}
  1543. #endif
  1544.  
  1545. #if !defined(BI_UNIQUE_BOOL)
  1546. inline TAutoVal::operator TAutoBool()    {return TAutoBool(operator TBool());}
  1547. inline TAutoVal::operator TAutoBoolRef() {return TAutoBoolRef(operator TBool*());}
  1548. #endif
  1549. inline TAutoVal::operator signed char()  {return operator unsigned char();}
  1550. inline TAutoVal::operator char()         {return operator unsigned char();}
  1551. inline TAutoVal::operator char*()        {return (char*)operator unsigned char*();}
  1552. inline TAutoVal::operator signed char*() {return (signed char*)operator unsigned char*();}
  1553.  
  1554. inline void TAutoVal::operator =(IUnknown*     ifc){vt=atUnknown; punkVal=ifc;}
  1555. inline void TAutoVal::operator =(IDispatch*    ifc){vt=atObject; pdispVal=ifc;}
  1556.  
  1557. #if defined(BI_PLAT_WIN32)
  1558. inline void TAutoVal::operator =(IPictureDisp* ifc){vt=atObject; pdispVal=ifc;}
  1559. inline void TAutoVal::operator =(IFontDisp*    ifc){vt=atObject; pdispVal=ifc;}
  1560. #endif
  1561.  
  1562. inline void TAutoVal::operator =(VARIANT&        v){vt=atVariant; pvarVal= &v;}
  1563. inline void TAutoVal::operator =(unsigned char   v){vt=atByte;   bVal  = v;}
  1564. inline void TAutoVal::operator =(signed   char   v){vt=atByte;   bVal  = v;}
  1565. inline void TAutoVal::operator =(char            v){vt=atByte;   bVal  = v;}
  1566. inline void TAutoVal::operator =(short           v){vt=atShort;  iVal  = v;}
  1567. inline void TAutoVal::operator =(long            v){vt=atLong;   lVal  = v;}
  1568. inline void TAutoVal::operator =(float           v){vt=atFloat;  fltVal= v;}
  1569. inline void TAutoVal::operator =(double          v){vt=atDouble; dblVal= v;}
  1570. inline void TAutoVal::operator =(TBool           v){vt=atBool;   boolVal = short(v ? -1 : 0);}
  1571. #if !defined(BI_UNIQUE_BOOL)
  1572. inline void TAutoVal::operator =(TAutoBool v){vt=atBool; boolVal = short((bool)v ? -1 : 0);}
  1573. #endif
  1574. inline void TAutoVal::operator =(TAutoDate     v){vt=atDatetime; date = v;}
  1575. inline void TAutoVal::operator =(TAutoCurrency v){vt=atCurrency; cyVal = v;}
  1576. inline void TAutoVal::operator =(TAutoVoid      ){vt=atVoid;}
  1577. inline void TAutoVal::operator =(const TNoArg&  ){vt=atError; scode=DISP_E_PARAMNOTFOUND;}
  1578.  
  1579. inline void TAutoVal::operator =(unsigned char* p){vt=atByte+atByRef; pbVal=p;}
  1580. inline void TAutoVal::operator =(signed char*   p){vt=atByte+atByRef; pbVal=(unsigned char*) p;}
  1581. inline void TAutoVal::operator =(char*          p){vt=atByte+atByRef; pbVal=(unsigned char*) p;}
  1582. inline void TAutoVal::operator =(short*         p){vt=atShort+atByRef; piVal=p;}
  1583. inline void TAutoVal::operator =(long*          p){vt=atLong+atByRef;  plVal=p;}
  1584. inline void TAutoVal::operator =(TBool*         p){vt=atBool+atByRef;  pbool=(VARIANT_BOOL*)p;}
  1585. #if !defined(BI_UNIQUE_BOOL)
  1586. inline void TAutoVal::operator =(TAutoBoolRef   p){vt=atBool+atByRef; pbool=(VARIANT_BOOL*)(bool*)p;}
  1587. #endif
  1588. inline void TAutoVal::operator =(float*         p){vt=atFloat+atByRef; pfltVal=p;}
  1589. inline void TAutoVal::operator =(double*        p){vt=atDouble+atByRef;pdblVal=p;}
  1590. inline void TAutoVal::operator =(TAutoDate*     p){vt=atDatetime+atByRef;pdate=(double*)p;}
  1591. inline void TAutoVal::operator =(TAutoCurrency* p){vt=atCurrency+atByRef;pcyVal=p;}
  1592.  
  1593. inline void TAutoVal::operator =(unsigned short  v){vt=atLong; lVal = (long)v;}
  1594. inline void TAutoVal::operator =(unsigned short* p){vt=atShort+atByRef; piVal = (short*)p;}
  1595. inline void TAutoVal::operator =(unsigned long   v){vt=atLong; lVal = (long)v;}
  1596. inline void TAutoVal::operator =(unsigned long*  p){vt=atLong+atByRef; plVal = (long*)p;}
  1597. #if (MAXINT==MAXSHORT)
  1598. inline void TAutoVal::operator =(int           v){vt=atShort; iVal=v;}
  1599. inline void TAutoVal::operator =(int*          p){vt=atShort+atByRef; piVal=(short*)p;}
  1600. inline void TAutoVal::operator =(unsigned int  v){operator =((unsigned short)v);}
  1601. inline void TAutoVal::operator =(unsigned int* p){operator =((unsigned short*)p);}
  1602. #else
  1603. inline void TAutoVal::operator =(int           v){vt=atLong; lVal=v;}
  1604. inline void TAutoVal::operator =(int*          p){vt=atLong+atByRef; plVal = (long*)p;}
  1605. inline void TAutoVal::operator =(unsigned int  v){operator =((unsigned long)v);}
  1606. inline void TAutoVal::operator =(unsigned int* p){operator =((unsigned long*)p);}
  1607. #endif
  1608.  
  1609. //
  1610. //
  1611. inline void TAutoVal::operator =(TObjectDescriptor od)
  1612. {
  1613.   vt = atObjectDesc;
  1614.   ObjDesc.Object= od.Object;
  1615.   ObjDesc.Class = od.Class;
  1616.   if (od.Destruct == TObjectDescriptor::Delete)
  1617.     vt |= atByRef;
  1618. }
  1619.  
  1620. //
  1621. //
  1622. inline int TAutoVal::GetDataType() const {
  1623.   return vt;
  1624. }
  1625.  
  1626. //
  1627. //
  1628. inline void TAutoVal::Init()
  1629. {
  1630.   memset(this, 0, sizeof(*this));
  1631. }
  1632.  
  1633. //
  1634. //
  1635. inline void TAutoVal::Clear()
  1636. {
  1637.   if ((vt & ~atByRef) == atLoanedBSTR) {
  1638.     s.Holder->ReleaseBstr((vt & atByRef) ? *pbstrVal : bstrVal);
  1639.     vt = uint16(atString | (vt & atByRef));
  1640.   }
  1641.   ::VariantClear((VARIANT*)this);
  1642. }
  1643.  
  1644. //
  1645. //
  1646. inline void TAutoVal::Restore()
  1647. {
  1648.   if ((vt & ~atByRef) == atLoanedBSTR) {
  1649.     s.Holder->RevokeBstr((vt & atByRef) ? *pbstrVal : bstrVal);
  1650.     vt = uint16(atString | (vt & atByRef));
  1651.   } else if (vt == uint16(atBool | atByRef) && *pbool != 0) {
  1652.     *pbool = -1;
  1653.   }
  1654.  
  1655.   // Need to check if atObjectDesc? Should never happen as it is temporary
  1656. }
  1657.  
  1658. //
  1659. //
  1660. inline void TAutoVal::Copy(const TAutoVal& copy)
  1661. {
  1662.   vt = copy.vt;
  1663.   p  = copy.p;
  1664.   if (vt == atUnknown || vt == atObject)
  1665.     punkVal->AddRef();
  1666.   if (vt == atString)
  1667.     bstrVal = ::SysAllocString(bstrVal);
  1668. }
  1669.  
  1670. // Converts TAutoVal/VARIANT to another type
  1671. // NOTE: Converts in-place if source is not specified
  1672. //
  1673. inline HRESULT TAutoVal::ChangeType(VARTYPE varType, TAutoVal* src) {
  1674.    return ::VariantChangeType((VARIANT*)this, src ? (VARIANT*)src : (VARIANT*)this, 0, varType);
  1675. }
  1676.  
  1677. // Is TAutoVal Object (i.e. VARIANT) passing data by reference
  1678. //
  1679. inline bool TAutoVal::IsRef() const {
  1680.   return (vt & atByRef) ? true : false;
  1681. }
  1682.  
  1683. //
  1684. //
  1685. inline TAutoVal* TAutoVal::DereferenceVariant() {
  1686.   return vt==atVariant+atByRef ? (TAutoVal*)pvarVal : this;
  1687. }
  1688.  
  1689. //
  1690. //
  1691. inline TString TAutoVal::StrVal() {
  1692.   return vt==atString ? bstrVal : 0;
  1693. }
  1694.  
  1695. //
  1696. //
  1697. inline bool TAutoVal::GetObjDesc(TObjectDescriptor& od)
  1698. {
  1699.   if ((char)vt != atObjectDesc)
  1700.     return false;
  1701.   od.Object = ObjDesc.Object;
  1702.   od.Class  = ObjDesc.Class;
  1703.   od.Destruct = IsRef() ? TObjectDescriptor::Delete : TObjectDescriptor::Quiet;
  1704.   return true;
  1705. }
  1706.  
  1707. //
  1708. //
  1709. inline SAFEARRAY* TAutoVal::GetArray()
  1710. {
  1711.   if (vt == atSafeArray)
  1712.     return parray;
  1713.   if (vt == (atSafeArray|atByRef))
  1714.     return *pparray;
  1715.   return 0;
  1716. }
  1717.  
  1718. //
  1719. //
  1720. inline void* TAutoVal::SetByRef(AutoDataType datatype)
  1721. {
  1722.   if (vt == atVariant)
  1723.     return this;
  1724.   vt = uint16(datatype);
  1725.   return &byref;
  1726. }
  1727.  
  1728. //____________________________________________________________________________
  1729. // TServedObject inlines
  1730.  
  1731. inline TServedObject::operator IDispatch*()
  1732. {
  1733.   AddRef();
  1734.   return (IDispatch*)this;  // essentially a quick QueryInterface on the obj
  1735. }
  1736.  
  1737. // TDispatch inlines
  1738.  
  1739. inline TDispatch::operator IDispatch*()
  1740. {
  1741.   AddRef();
  1742.   return (IDispatch*)this;  // essentially a quick QueryInterface on the obj
  1743. }
  1744.  
  1745. //____________________________________________________________________________
  1746.  
  1747. // TAutoCommand inlines
  1748.  
  1749. inline TAutoCommand::TAutoCommand(int attr) : Attr(attr), Symbol(0) {}
  1750. inline void TAutoCommand::SetFlag(int mask) {Attr |= mask;}
  1751. inline void TAutoCommand::ClearFlag(int mask) {Attr&=(~mask);}
  1752. inline bool TAutoCommand::TestFlag(int mask) {return ToBool((Attr&mask)==mask);}
  1753. inline bool TAutoCommand::IsPropSet() {return TestFlag(asSet);}
  1754. inline TAutoSymbol* TAutoCommand::GetSymbol() {return Symbol;}
  1755. inline void TAutoCommand::SetSymbol(TAutoSymbol* sym) {Symbol = sym;}
  1756. inline const char* TAutoCommand::LookupError(long errCode)
  1757.     {return TAutoCommand_ErrorLookup ? TAutoCommand_ErrorLookup(errCode) : 0;}
  1758. //____________________________________________________________________________
  1759.  
  1760. // TAutoEnum inlines and template function definitions
  1761.  
  1762. inline TAutoEnum::TAutoEnum(int count, int type)
  1763.                         : Count(count) { Type = short(type + atEnum); }
  1764.  
  1765. template <class T> inline
  1766. TAutoEnumT<T>::TAutoEnumT(TAutoEnumVal<T>* table, int symcount, int type)
  1767. : TAutoEnum(symcount, type), Table(table) {}
  1768.  
  1769. // incoming enumeration string localized lookup
  1770. //
  1771. template <class T> bool
  1772. TAutoEnumT<T>::Convert(TAutoVal& txtVal, TAutoVal& numVal)
  1773. {
  1774.   TString& stringRef = txtVal.StrVal();  // 0 if not string type
  1775.   const char* str = stringRef;
  1776.   if (str) {
  1777.     TLangId langId = txtVal.GetLanguage();
  1778.     for (int i = 0; i < Count; i++) {
  1779.       if (Table[i].Name.Compare(str, langId) == 0) {
  1780.         numVal = Table[i].Val;
  1781.         return true;
  1782.       }
  1783.     }
  1784.   }
  1785.   return false;
  1786. }
  1787.  
  1788. // outgoing enumeration translation to localized string
  1789. //
  1790. template <class T> bool
  1791. TAutoEnumT<T>::Convert(TAutoVal& numVal, TLangId langId)
  1792. {
  1793.   T val;
  1794.   val = numVal;  // perhaps we should put a try/catch here!!
  1795.   for (int i = 0; i < Count; i++) {
  1796.     if (Table[i].Val == val) {
  1797.       numVal = Table[i].Name.Translate(langId);
  1798.       numVal.SetLocale(langId);
  1799.       return true;
  1800.     }
  1801.   }
  1802.   return false;
  1803. }
  1804.  
  1805. // special case for outgoing string enumerations
  1806. //
  1807. #pragma warn -inl
  1808. inline bool
  1809. TAutoEnumT<const char*>::Convert(TAutoVal& numVal, TLangId langId)
  1810. {
  1811.   const char* str = numVal.StrVal();  // 0 if not string type
  1812.   if (str)
  1813.     for (int i = 0; i < Count; i++) {
  1814.       if (lstrcmp(Table[i].Val, str) == 0) {
  1815.         numVal = Table[i].Name.Translate(langId);
  1816.         numVal.SetLocale(langId);
  1817.         return true;
  1818.       }
  1819.     }
  1820.   return false;
  1821. }
  1822. #pragma warn .inl
  1823.  
  1824. //____________________________________________________________________________
  1825.  
  1826. // TAutoIterator inlines
  1827.  
  1828. inline TAutoIterator::operator IUnknown*() {RefCnt++; return this;}
  1829. inline TAutoSymbol* TAutoIterator::GetSymbol() {return Symbol;}
  1830. inline void TAutoIterator::SetSymbol(TAutoSymbol* sym) {Symbol = sym;}
  1831.  
  1832. //____________________________________________________________________________
  1833. //
  1834. // Inline implementations for automation server - part 2
  1835. //   These are inline only for the purpose of allowing _AUTOCLASS
  1836. //   to be specified at compile time without rebuilding OCF library
  1837. //   This applies to classes: TAutoBase, TAutoCommand, TAutoDetach
  1838. //____________________________________________________________________________
  1839.  
  1840. inline TAutoBase::~TAutoBase()
  1841. {
  1842.   ::SendObituary(this, typeid(TAutoBase));
  1843. }
  1844.  
  1845. inline void TAutoDetach::Notify(int offset, const typeinfo& typeInfo)
  1846. {
  1847.   ::SendObituary((char*)this-offset, typeInfo);
  1848. }
  1849. //____________________________________________________________________________
  1850.  
  1851. // TAutoCommand implementation specified inline to avoid _AUTOCLASS link errors
  1852.  
  1853. inline void TAutoCommand::Fail(TXAuto::TError err) { throw TXAuto(err); }
  1854.  
  1855. inline bool TAutoCommand::Validate() { return true; }
  1856.  
  1857. inline TAutoCommand& TAutoCommand::Invoke()
  1858. {
  1859.   if (!TAutoCommand_InvokeHook || TAutoCommand_InvokeHook(*this))
  1860.     Execute();
  1861.   return *this;
  1862. }
  1863.  
  1864. inline void TAutoCommand::Execute()
  1865. {
  1866. }
  1867.  
  1868. inline long TAutoCommand::Report()
  1869. {
  1870.   return 0;
  1871. }
  1872.  
  1873. inline void TAutoCommand::Return(TAutoVal& v)
  1874. {
  1875.   v = TAutoVoid();
  1876. }
  1877.  
  1878. inline void TAutoCommand::Transfer(TAutoTransfer& x)
  1879. {
  1880. }
  1881.  
  1882. inline TAutoCommand* TAutoCommand::Undo() {return 0;}
  1883.  
  1884. inline int TAutoCommand::Record(TAutoStack&) {return 0;}
  1885.  
  1886. inline TAutoCommand::TErrorMsgHook
  1887. TAutoCommand::SetErrorMsgHook(TAutoCommand::TErrorMsgHook callback){
  1888.   TErrorMsgHook hook = TAutoCommand_ErrorLookup;
  1889.   TAutoCommand_ErrorLookup = callback;
  1890.   return hook;
  1891. }
  1892.  
  1893. inline TAutoCommand::TCommandHook
  1894. TAutoCommand::SetCommandHook(TAutoCommand::TCommandHook callback){
  1895.   TCommandHook hook = TAutoCommand_InvokeHook;
  1896.   TAutoCommand_InvokeHook = callback;
  1897.   return hook;
  1898. }
  1899.  
  1900. #endif  // OCF_AUTODEFS_H
  1901.  
  1902.  
  1903.